﻿using NModbus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace CentralMonitoring.Protocol
{
    public class GasContent
    {
        public static async Task<ushort[]> ModbusRtuTcpReadRegisters(byte slaveId, ushort startAddress, ushort length)
        {
            var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            {
                // configure socket
                INIFile ini = new INIFile("config.ini");
                string ip = ini.IniReadValue("GasContent", "DeviceIp");
                string port = ini.IniReadValue("GasContent", "DevicePort");
                var serverIP = IPAddress.Parse(ip);
                var serverFullAddr = new IPEndPoint(serverIP, int.Parse(port));
                try
                {
                    sock.Connect(serverFullAddr);
                }
                catch (Exception)
                {
                    return null;
                }

                var factory = new ModbusFactory();
                IModbusMaster master = factory.CreateMaster(sock);

                ushort[] registers = null;
                var cts = new CancellationTokenSource();
                // 创建一个定时器
                Timer timer = new Timer(async (state) =>
                {
                    try
                    {
                        // 在这里进行读取操作
                        var res = await master.ReadHoldingRegistersAsync(slaveId, startAddress, length);
                        registers = res;
                        if (res != null)
                            if (!cts.IsCancellationRequested)
                                cts.Cancel();
                            else
                                return;
                    }
                    catch (Exception)
                    {
                        // 处理异常，例如记录日志
                        //Console.WriteLine($"Error occurred: {ex.Message}");
                        registers = null;
                    }
                }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); // 从现在开始，每 1 秒执行一次

                // 等待一段时间，以便定时器有机会执行
                try
                {
                    await Task.Delay(TimeSpan.FromSeconds(5), cts.Token);
                }
                catch (Exception)
                {
                    // 任务被取消时的处理，可根据需要添加逻辑
                    //timer.Dispose();
                }

                // 停止定时器
                timer.Dispose();

                return registers;
            }
        }

        public static async Task<GasContentModel> GetData()
        {
            GasContentModel model = null;
            bool state = false;
            INIFile ini = new INIFile("config.ini");
            string SlaveId = ini.IniReadValue("GasContent", "SlaveId");
            await Task.Run(async () =>
            {
                // 测试连接状态
                var res = await ModbusRtuTcpReadRegisters(byte.Parse(SlaveId), 0x0004, 1);
                if (res == null) return;
                state = true;
            });
            if (!state) return model;

            model = new GasContentModel();
            await Task.Run(async () =>
            {
                var res = await ModbusRtuTcpReadRegisters(byte.Parse(SlaveId), 0x0004, 12);
                int i = 0;
                model.CurrentStatus = (int)(res[i] << 16 | res[i + 1]);
                i += 2;
                model.EnvironmentTemperature = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.AtmosphericPressure = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.DegassingTemperature = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.DataAnalysisCount = (int)(res[i] << 16 | res[i + 1]);
                i += 2;
                model.GasContent = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
            });

            return model;
        }
    }

    public class GasContentModel
    {
        /// <summary>
        /// 当前状态
        /// </summary>
        public int CurrentStatus { get; set; }

        /// <summary>
        /// 读环境实时温度
        /// </summary>
        public float EnvironmentTemperature { get; set; }

        /// <summary>
        /// 读环境大气压
        /// </summary>
        public float AtmosphericPressure { get; set; }

        /// <summary>
        /// 脱气温度
        /// </summary>
        public float DegassingTemperature { get; set; }

        /// <summary>
        /// 读当数据分析次数
        /// </summary>
        public int DataAnalysisCount { get; set; }

        /// <summary>
        /// 读含气量
        /// </summary>
        public float GasContent { get; set; }

        //// 0x0002H 存储环境实时温度的寄存器
        //public float EnvironmentTemperature { get; set; }
        //// 0x0004H 存储脱气实时温度的寄存器
        //public float DegassingTemperature { get; set; }
        //// 0x0006H 存储环境大气压的寄存器
        //public float AtmosphericPressure { get; set; }
        //// 0x0008H 存储已完成次数的寄存器
        //public long CompletedCount { get; set; }
        //// 0x000EH 存储含气量的寄存器
        //public float GasContent { get; set; }
        //// 0x0010H 存储状态信息的寄存器
        //public long StatusInfo { get; set; }
    }
}
